//
//  ChatBubbleContentViewModel.swift
//  Chatup
//
//  Created by iron man on 2024/2/19.
//

import Foundation

enum MessageStatus {
    case none
    case loading
    case error
    case success
}


@MainActor
class ChatBubbleContentViewModel :ObservableObject{
    @Published var model:MessageModel
    //是否需要包裹
    @Published var needBubble:Bool = true
    //是否需要功能按钮
    @Published var needTool: Bool = true
    //消息状态
    @Published var status: MessageStatus = .none
    //边距
    @Published var padding: CGFloat = 14
    var roleId:String
    init(model: MessageModel) {
        self.model = model
        self.roleId = model.roleId ?? "-1"
        self.needBubble = model.messageType == .text || model.messageType == .assetsImage || model.messageType == .netWorkImage
        self.needTool = model.messageType == .text && status != .loading
        self.padding = model.messageType == .text ? 14 : 6
        if !model.isUser && model.context != nil{
            self.status = .none
            //feature
            if model.messageFeaturesType == .drawImage{
                self.status = .loading
                drawImage()
            }else if model.messageFeaturesType == .recognizeImage{
                recognizeImage()
            }else if model.messageFeaturesType == .link{
                link()
            }else if model.messageFeaturesType == .document{
                documentText()
            }else if model.messageFeaturesType == .emojy{
                getEmojy()
            }else if model.messageFeaturesType == .translate{
                translateText()
            }else{
                talk()
            }
        }
    }
    
    // 消息体状态变更
    func setStatus(s: MessageStatus){
        self.status = s
    }
    
    func drawImage(){
        self.status = .loading
        DrawImageMessageBuilder().buildMessage(resouse: model.context!, message: { url in
 
            DispatchQueue.main.async {
                if url == nil || url == "0" {
                    self.status = .error
                    let imgModel = MsgModel(type: .bot, messageType: .text, message: "something wrong happens，please check your network and tetry", roleId: 0, isLike: false, isUnlike: false)
                    MassageDataManager.share.saveMsgs(msgs: [imgModel])
                    return
                }
                
                if url == "-1"{
                    self.status = .error
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: Notification.Name("kGpt3OverSizeMessage"), object: nil)
                    }
                    return
                }
                
                if url == "-2" {
                    DispatchQueue.main.async {
                        
                        NotificationCenter.default.post(name: Notification.Name("kGpt4OverSizeMessage"), object: nil)
                    }
                    
                    return
                }
                
                if url == "-3" {
                    DispatchQueue.main.async {
                        
                        NotificationCenter.default.post(name: Notification.Name("kDrawImageOverSizeMessage"), object: nil)
                    }
                    
                    return
                }
                self.model = MessageModel(isUser: self.model.isUser, messageType: self.model.messageType, robotIcon: self.model.robotIcon, message: url!, isFinish: true, isStart: self.model.isStart,roleId: self.model.roleId)
                NotificationCenter.default.post(name: Notification.Name("kUpdateLaseMessage"), object: self.model)
                self.status = .none
                let imgModel = MsgModel(type: .bot, messageType: .networkImage, message: url!, roleId: 0, isLike: false, isUnlike: false)
                MassageDataManager.share.saveMsgs(msgs: [imgModel])
            }
            
        })
    }
    
    func talk(){
        var mode = UserDefaults.standard.string(forKey: "mode") ?? "gpt3"
        self.status = .loading
        var text = ""
        if Int(model.roleId ?? "0") != 0{
            mode = "gpt3"
        }
 
       
        RequestManager.shared.postWithStream("https://backend.aichattings.com/api/v2/chatgpt/talk", params: params(msg: model.context!, mode: mode, roleId: model.roleId ?? "0")) { data, code in
            
            DispatchQueue.main.async { [self] in
                if status == .error{
                    
                }else{
                    model = MessageModel(isUser: model.isUser, messageType: model.messageType, robotIcon: model.robotIcon, message: text, isFinish: true, isStart: model.isStart,roleId: roleId)
                    NotificationCenter.default.post(name: Notification.Name("kUpdateLaseMessage"), object: model)
                    let imgModel = MsgModel(type: .bot, messageType: .text, message: text, roleId: Int(roleId)!, isLike: false, isUnlike: false)
                 
                    MassageDataManager.share.saveMsgs(msgs: [imgModel])
                    
                    let role = RoleDataManager.share.getRole(roleId: Int(roleId)!)
                    let datas = MassageDataManager.share.getMsg(roleId: Int(roleId)!)
                    
                    let count = datas.filter { data in
                        data.isBot() && !data.isImage()
                    }.count
                    let imageMessageInterval = 5
                    if count % imageMessageInterval == 1 && role?.images.count ?? 0 > 0{
                        let imgModel = MsgModel(type: .bot, messageType: .image, message: role?.currentImage() ?? "", roleId: Int(roleId)!, isLike: false, isUnlike: false)
                        MassageDataManager.share.saveMsg(msg: imgModel)
                        role?.imageIndex = (role?.imageIndex ?? 1) + 1
                        RoleDataManager.share.updateRole(role:role!)
                        NotificationCenter.default.post(name: Notification.Name("kAppendMessage"), object: ["feature":FeaturesType.talk,"msgs":[imgModel],"roleId":roleId])
                    }

                }

            }
        } fail: {t, code, msg in
            
            DispatchQueue.main.async { [self] in
                status = .error
                model = MessageModel(isUser: model.isUser, messageType: model.messageType, robotIcon: model.robotIcon, message: "something wrong happens，please check your network and tetry", isFinish: true, isStart: model.isStart)
                NotificationCenter.default.post(name: Notification.Name("kUpdateLaseMessage"), object: model)
                if code == -1 {
                    NotificationCenter.default.post(name: Notification.Name("kGpt3OverSizeMessage"), object: nil)
                }else if code == -2 {
                    NotificationCenter.default.post(name: Notification.Name("kGpt4OverSizeMessage"), object: nil)
                }
            }
            
        } reading: { [self]str in
            DispatchQueue.main.async {
                var strIn = str
                if strIn == "" {
                    strIn = "\n\n"
                }
                text = text + strIn
                self.model = MessageModel(isUser: self.model.isUser, messageType: self.model.messageType, robotIcon: self.model.robotIcon, message: text, isFinish: false, isStart: self.model.isStart)
                self.status = .none
                NotificationCenter.default.post(name: Notification.Name("kScrollToBottom"), object: self.model)
            }
        }

    }
    
    func getEmojy(){
        talk()
    }
    
    func translateText(){
        talk()
    }
    
    func link(){
        talk()
    }
    
    func documentText(){
        self.status = .loading
        let list = model.context!.components(separatedBy: "#")

        FileMessageBuilder().buildMessage(resouse: URL(string: list.last!) ?? URL(fileURLWithPath: ""),question: list.first!, message: { m in

            DispatchQueue.main.async {
                guard let message = m else {
                    self.status = .error
        
                    let imgModel = MsgModel(type: .bot, messageType: .text, message: "something wrong happens，please check your network and tetry", roleId: 0, isLike: false, isUnlike: false)
                    MassageDataManager.share.saveMsgs(msgs: [imgModel])
                    return
                }
                if message == "-1"{
                    self.status = .error
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: Notification.Name("kGpt3OverSizeMessage"), object: nil)
                    }
                    return
                }
                
                if message == "-2" {
                    self.status = .error
                    DispatchQueue.main.async {
                        
                        NotificationCenter.default.post(name: Notification.Name("kGpt4OverSizeMessage"), object: nil)
                    }
                    
                    return
                }
                
    
                self.model = MessageModel(isUser: self.model.isUser, messageType: self.model.messageType, robotIcon: self.model.robotIcon, message: message, isFinish: true, isStart: self.model.isStart)
                NotificationCenter.default.post(name: Notification.Name("kUpdateLaseMessage"), object: self.model)
                let imgModel = MsgModel(type: .bot, messageType: .text, message: message, roleId: 0, isLike: false, isUnlike: false)
                MassageDataManager.share.saveMsgs(msgs: [imgModel])
                self.status = .none
            }
            
        })
    }
    
    func recognizeImage(){
        self.status = .loading
        let list = model.context!.components(separatedBy: "#")
        RecognizeImageMessageBuilder().buildMessage(resouse: list.first!, question: list.last!) { url in
            if url == nil {
                self.status = .error
                return
            }
            
            if url == "-1"{
                self.status = .error
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: Notification.Name("kGpt3OverSizeMessage"), object: nil)
                }
                return
            }
            
            if url == "-2" {
                DispatchQueue.main.async {
                    
                    NotificationCenter.default.post(name: Notification.Name("kGpt4OverSizeMessage"), object: nil)
                }
                
                return
            }
            
            DispatchQueue.main.async {
                self.model = MessageModel(isUser: self.model.isUser, messageType: self.model.messageType, robotIcon: self.model.robotIcon, message: url!, isFinish: true, isStart: self.model.isStart)
                NotificationCenter.default.post(name: Notification.Name("kUpdateLaseMessage"), object: self.model)
                self.status = .none
                let imgModel = MsgModel(type: .bot, messageType: .text, message: url!, roleId: 0, isLike: false, isUnlike: false)
                MassageDataManager.share.saveMsgs(msgs: [imgModel])
            }
        }
    }
    
    private func params(msg: String, mode: String, roleId: String) -> [String: String]? {
        guard let uuid = UserDefaults.standard.string(forKey: "uuid") else { return nil }
        return ["msg": msg,
                "uuid": uuid,
                "role_id": String(roleId),
                "model": mode,
                "ep_user_id": UserDefaults.standard.string(forKey: "ep_user_id") ?? "1",
                "endpoint": "ios"]
    }
}
